Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FM2-653 #556

Merged
merged 12 commits into from
Jan 24, 2025
Merged

FM2-653 #556

merged 12 commits into from
Jan 24, 2025

Conversation

mogoodrich
Copy link
Member

@mogoodrich mogoodrich commented Jan 9, 2025

Description of what I changed

Issue I worked on

https://openmrs.atlassian.net/browse/FM2-653

Checklist: I completed these to help reviewers :)

  • My IDE is configured to follow the code style of this project.

    No? Unsure? -> configure your IDE, format the code and add the changes with git add . && git commit --amend

  • I have added tests to cover my changes. (If you refactored
    existing code that was well tested you do not have to add tests)

    No? -> write tests and add them to this commit git add . && git commit --amend

  • I ran mvn clean package right before creating this pull request and
    added all formatting changes to my commit.

    No? -> execute above command

  • All new and existing tests passed.

    No? -> figure out why and add the fix to your commit. It is your responsibility to make sure your code works.

  • My pull request is based on the latest changes of the master branch.

    No? Unsure? -> execute command git pull --rebase upstream master

@@ -38,6 +41,8 @@
@Setter(AccessLevel.PACKAGE)
public class FhirLocationDaoImpl extends BaseFhirDao<Location> implements FhirLocationDao {

private static final int SUPPORTED_LOCATION_HIERARCHY_SEARCH_DEPTH = 9;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, I use a succession of joins to go back up the ancestor tree. A bit annoying/hacky, but from a practical matter, seems unlikely there would ever be a hierarchy of more than 9 levels. We could make this a configurable parameter if we wanted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we turn this into a GP? That way an implementation can adjust it to the actual depth of their location hierarchy.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough, I will do that (and since it's configurable, set a more normal default of like 5)

private void handleAncestorLocation(Criteria criteria, ReferenceAndListParam ancestor) {

List<Criterion> elementOrAncestorEqualsReferenceCriteria = new ArrayList<>();
Optional<Criterion> elementEqualsReferenceCriterion = handleLocationReference(ancestor); // note: "below" is inclusive of the element itself
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mogoodrich mogoodrich requested review from ibacher and mseaton January 9, 2025 21:40
@@ -113,6 +113,9 @@ public IBundleProvider searchLocations(@OptionalParam(name = Location.SP_NAME) S
@OptionalParam(name = Location.SP_PARTOF, chainWhitelist = { "", Location.SP_NAME, Location.SP_ADDRESS_CITY,
Location.SP_ADDRESS_STATE, Location.SP_ADDRESS_COUNTRY,
Location.SP_ADDRESS_POSTALCODE }, targetTypes = Location.class) ReferenceAndListParam parent,
@OptionalParam(name = "below", chainWhitelist = { "", Location.SP_NAME, Location.SP_ADDRESS_CITY,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it sounds like @ibacher this extra parameter should not be here, and this new functionality should just be part of the "SP_PARTOF" parameter above? I was having a problem with that, see my follow on comment and screenshot in the test case below.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The tl;dr is that if I change this to name="partof:below" any parameter passed in that way gets assigned to both the ReferenceAndListParam ancestor and ReferenceAndListParam parent.

And if I remove the "below" parameter, I'm not quite sure how to parse the "parent" ReferenceAndListParam to tell if this should be a standard "partof" vs a "partof:below"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this extra parameter should not be here, and this new functionality should just be part of the "SP_PARTOF" parameter above?

Ideally, yes.

And if I remove the "below" parameter, I'm not quite sure how to parse the "parent" ReferenceAndListParam to tell if this should be a standard "partof" vs a "partof:below"

That's very problematic. The problem is that partof=123abc&partof:below=456def is technically valid and I'm not quite sure what HAPI would do with that...

@@ -483,6 +486,31 @@ public void shouldSearchForExistingLocationsAsJson() throws Exception {
assertThat(entries, containsInRelativeOrder(hasResource(hasProperty("name", equalTo("Test location 6"))),
hasResource(hasProperty("name", equalTo("Test location 8")))));
assertThat(entries, everyItem(hasResource(validResource())));

// search by ancestors
response = get("/Location?below=" + LOCATION_ANCESTOR_TEST_UUID).accept(FhirMediaTypes.JSON).go();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So when I changed this to "Location?partof:below=" it was getting picked up by the ResourceParam, but the "below" was being set to the ResourceType. This seems incorrect? Isn't the type of this resource a location?

image

handleLocationReference("loc", parent).ifPresent(loc -> criteria.createAlias("parentLocation", "loc").add(loc));
private void handleLocationReference(Criteria criteria, ReferenceAndListParam locationAndReferences) {

if (locationAndReferences == null) {
Copy link
Member Author

@mogoodrich mogoodrich Jan 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this through 148 is basically a series null / size checks to make sure that ReferenceAnd list only contains a single reference. We probably should change this parameter to just a ReferenceParam but I didn't want to untangle the locationReference utility method at this point.

Basically, the "partof:below" functionality I built currently only works correctly for a single parameter (and I don't have the need to build more now). Technically the plain "partof" works for multiple "partof", but would always return null since a location partof is 0..1

@mogoodrich
Copy link
Member Author

@ibacher sorry, just another ping on this, can you take a look when you get a chance? This is basically updating things based on what we discussed when you were in Boston last week.

Copy link
Member

@ibacher ibacher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @mogoodrich! I think this basically looks as good as we can get it!


// we need to add a join to the parentLocation for each level of hierarchy we want to search, and add "equals" criterion for each level
int depth = 1;
while (depth <= SUPPORTED_LOCATION_HIERARCHY_SEARCH_DEPTH) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be a for loop?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean aesthetically, or is there a bug here I'm missing? :) For some reason I tend to prefer while loops.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just aesthetics. It looks like it works.

@@ -38,6 +41,8 @@
@Setter(AccessLevel.PACKAGE)
public class FhirLocationDaoImpl extends BaseFhirDao<Location> implements FhirLocationDao {

private static final int SUPPORTED_LOCATION_HIERARCHY_SEARCH_DEPTH = 9;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we turn this into a GP? That way an implementation can adjust it to the actual depth of their location hierarchy.

@mogoodrich
Copy link
Member Author

@ibacher updated to make search depth a global property as you suggested. Will merge assuming all tests pass.

@mogoodrich
Copy link
Member Author

Merging, thanks @ibacher !

@mogoodrich mogoodrich merged commit 0e04589 into master Jan 24, 2025
2 checks passed
@mogoodrich mogoodrich deleted the FM2-653 branch January 24, 2025 22:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants